package com.codefish;

import java.util.HashMap;
import java.util.Map;

/**
 * 抽象的类加载器
 *
 * @author codefish
 * @version 1.0
 * @date 2022/06/12 下午 09:51
 */
public abstract class SimpleClassLoader {
    /**
     * 注册中心，指定哪些类由自身加载
     */
    Map<String, String> registry = new HashMap<>();
    /**
     * 该加载器的父加载器
     */
    SimpleClassLoader parentClassLoader;
    /**
     * 类加载器的名称
     */
    String loaderName;

    public SimpleClassLoader(SimpleClassLoader parentClassLoader) {
        initRegistry();
        this.parentClassLoader = parentClassLoader;
    }


    /**
     * 加载类并返回类对象,采用双亲委派机制,我们不希望用户自定义的类加载器破坏双亲委派机制，因此方法修饰为final
     *
     * @param className 类的名称
     * @return 类对象
     */
    public final String loadClass(String className) {
        //交由父加载器加载类
        String object = null;
        if (parentClassLoader != null) {
            object = parentClassLoader.loadClass(className);
        }
        if (object != null) {
            return object;
        }
        //父加载器无法加载类，自身尝试加载
        object = loadClassSelf(className);
        if (object == null) {
            System.out.println((loaderName + "类加载器无法加载类" + className));
        } else {
            System.out.println(loaderName + "类加载器成功加载类" + className);
        }
        return object;
    }


    /**
     * 初始化注册中心，所有该加载器可加载的类用key占位，value设为null
     */
    public abstract void initRegistry();

    /**
     * 自身尝试加载类
     *
     * @param className 泪目
     * @return 类对象
     */
    protected String loadClassSelf(String className) {
        String object = null;
        if (registry.containsKey(className)) {
            object = registry.computeIfAbsent(className, k -> k.substring(0, k.indexOf(".")));
        }
        return object;
    }

}
